<?php

namespace ulue\core\db;

use Ulue,
    Debug,
    Trigger;
use ulue\core\db\base\AbstractDbDriver;

abstract class DriverFactory
{
    private static $driverMap    = [];      //驱动对象列表

    /**
     * 载入驱动，实例化对应的 driverMap[$driver] 驱动
     * @param string $driver
     * @param array $config [数据库配置]
     * @param bool $reConnect
     * @throws \DInvalidArgumentException
     * @return mixed
     */
    static public function getDriver( $driver = '', array $config=[], $reConnect = false )
    {
        if ($driver) {
            $driver = trim($driver);
        } if ( isset($config['driver']) ) {
            $driver = trim($config['driver']);
        } elseif (isset($config['dsn'])) {
            $driver = trim( strstr($config['dsn'], ':', true) );
        }

        if (!$driver) {
            throw new \DInvalidArgumentException('必须设置需要的数据库驱动类型名称');
        }

        if ( empty($config['driver']) ) {
            $config['driver'] = $driver;
        }

        $key    = self::buildKey( $config );

        // 已经连接并且没有要求强制重连 返回
        if (isset(self::$driverMap[$driver][$key]) && !$reConnect) {
            return self::$driverMap[$driver][$key];
        }

        Debug::trace('i 准备获取数据库操作实例，并连接到数据库。', $config);

        $classId     = '\ulue\core\db\%s\driver\%sDriver';
        $driverClass = sprintf($classId, $driver, ucfirst($driver));

        /**
         * @var $db AbstractDbDriver
         */
        $db        = new $driverClass(null, $config);
        self::$driverMap[$driver][$key] = $db->connect();

        Debug::trace("数据库操作类实例化完毕，成功连接到数据库 [$db->name:$db->database]。".Debug::countTime(),[
            '数据库驱动类'          => $driverClass,
            '@attribute $driverMap' => array_keys(self::$driverMap)
            ]);

        unset($config, $driverClass, $db, $classId);

        return self::$driverMap[$driver][$key];
    }

    static public function setDriver($driver, AbstractDbDriver $connect)
    {
        $driver = strtolower($driver);
        $key    = self::buildKey($connect->getOptions());

        static::$driverMap[$driver][$key] = $connect;
    }

    /**
     *
     * @param  array $options
     * @return string
     */
    static public function buildKey($options)
    {
        $host     = isset($options['host']) ? $options['host']: 'localhost';
        $port     = isset($options['port']) ? $options['port']: '3306';
        $database = $options['database'];

        return md5($host. $port. $database);
    }

    /**
     * 获取最近的数据库链接实例
     * @param  string $value [description]
     * @return [type]        [description]
     */
    static public function getLastDriver($driver)
    {
        return isset(static::$driverMap[$driver]) ? end(self::$driverMap[$driver]) : null;
    }


}